package atom.core3.security;

//运行本程序你需要下载JCE，Bouncy Castle
import java.io.FileInputStream;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;

import org.apache.log4j.Logger;

/**
 * <p>
 * Title:数字签名工具类。支持对文件的签名
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: Copyright (c) 2004
 * </p>
 * <p>
 * </p>
 * 
 * @author 赵明才
 * @version 1.0
 */
public class JSignVerify
{

	private static Logger log = Logger.getLogger(JSignVerify.class);
	PrivateKey priKey;
	PublicKey pubKey;

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		try
		{

			JSignVerify signverify = new JSignVerify();
			PrivateKey priKey=null;
			PublicKey pubKey=null;
			signverify.setKey(priKey, pubKey);
			byte[] a = signverify.SignFile("d:\\药店进价一览表1.xls");
			signverify.VerifyFileMD5("d:\\药店进价一览表1.xls", a, a.length);
			// byte[] b1= signverify.RSAEncrypt("123ert".getBytes());
			// byte[] b2= signverify.RSADecrypt(b1);
			// System.out.println(new String(b2));
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
		}
	}
	public void setKey(PrivateKey priKey,PublicKey pubKey)
	{
		this.priKey = priKey;
		this.pubKey = pubKey;
	}
	// 签名algorithm="SHA1withRSA" "MD5withRSA"
	public byte[] SignMemory(byte[] info, String algorithm) throws Exception
	{
		// 用私钥对信息生成数字签名
		java.security.Signature signet = java.security.Signature.getInstance(algorithm);// MD5withRSA//
		signet.initSign(priKey);
		signet.update(info);
		byte[] signed = signet.sign(); // 对信息的数字签名
		return signed;
	}

	// 验证内存签名
	public boolean VerifyMemoryMD5(byte[] info, byte[] signed) throws Exception
	{
		return VerifyMemory(info, signed, "MD5withRSA");
	}

	public boolean VerifyMemorySHA1(byte[] info, byte[] signed) throws Exception
	{
		return VerifyMemory(info, signed, "SHA1withRSA");
	}

	public boolean VerifyMemory(byte[] info, byte[] signed, String method) throws Exception
	{
		// method = "SHA1withRSA" "MD5withRSA"
		java.security.Signature signetcheck = java.security.Signature.getInstance(method);
		signetcheck.initVerify(pubKey);
		signetcheck.update(info);
		if (signetcheck.verify(signed))
		{
			System.out.println("验证签名正常");
			return true;
		}
		else
		{
			System.out.println("验证签名失败");
			return false;
		}

	}

	public byte[] SignFile(String inFile) throws Exception
	{
		byte[] buf = new byte[1024];
		int num;
		FileInputStream fin = new FileInputStream(inFile);
		// String myinfo =
		// "orderId=10dkfadsfksdkssdkd&amount=80&orderTime=20060509"; // 要签名的信息
		// signet.update(myinfo.getBytes("ISO-8859-1"));

		// 用私钥对信息生成数字签名
		java.security.Signature signet = java.security.Signature.getInstance("MD5withRSA");
		signet.initSign(priKey);

		while ((num = fin.read(buf, 0, buf.length)) != -1)
		{
			signet.update(buf, 0, num);
		}

		byte[] signed = signet.sign(); // 对信息的数字签名
		fin.close();
		System.out.println("签名并生成文件成功");
		return signed;
	}

	public boolean VerifyFileMD5(String inFile, byte[] pSigBuf, int SigLen) throws Exception
	{
		return VerifyFile(inFile, pSigBuf, SigLen, "MD5withRSA");
	}

	public boolean VerifyFileSHA1(String inFile, byte[] pSigBuf, int SigLen) throws Exception
	{
		return VerifyFile(inFile, pSigBuf, SigLen, "SHA1withRSA");
	}

	public boolean VerifyFile(String inFile, byte[] pSigBuf, int SigLen, String method) throws Exception
	{
		// method = "MD5withRSA" "SHA1withRSA"
		byte[] buf = new byte[1024];
		int num;
		FileInputStream fin = new FileInputStream(inFile);

		java.security.Signature signetcheck = java.security.Signature.getInstance(method);
		signetcheck.initVerify(pubKey);
		while ((num = fin.read(buf, 0, buf.length)) != -1)
		{
			signetcheck.update(buf, 0, num);
		}
		fin.close();
		if (signetcheck.verify(pSigBuf, 0, SigLen))
		{
			System.out.println("签名正常");
			return true;
		}
		else
		{
			System.out.println("非签名正常");
			return false;
		}

	}

	// 公钥加密
	public byte[] RSAEncrypt(byte[] buf) throws Exception
	{
		Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		// Cipher rsaCipher=Cipher.getInstance("RSA");
		rsaCipher.init(Cipher.ENCRYPT_MODE, pubKey);
		rsaCipher.update(buf);
		return rsaCipher.doFinal();

	}

	// 私钥解密
	public byte[] RSADecrypt(byte[] buf) throws Exception
	{
		Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

		rsaCipher.init(Cipher.DECRYPT_MODE, priKey);
		rsaCipher.update(buf);
		return rsaCipher.doFinal();

	}

	public byte[] PrivatekeyDecrypt(byte[] cipherText) throws Exception
	{
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		byte[] plainText = cipher.doFinal(cipherText);

		return plainText;

	}
}
